Day 17 : 用於生產的機械學習 - 特徵選擇 Feature Selection
tags: MLOps
特徵選擇是機器學習中的核心概念之一,不相關或部分相關的特徵會對模型性能產生負面影響,也會有效能的問題,適當的挑選與目標變量最相關的特徵集,有助降低模型的複雜性,並最大限度地減少訓練和推理所需的資源。這在您可能處理 TB 級數據或服務數百萬個請求的生產模型中具有更大的影響,以下說明幾個特徵選擇的作法。
特徵選擇方法
- 非監督式學習
- 可以採取移除關聯較低的特徵策略,減少無關的特徵。
- 監督式學習
- 關聯度高的特徵通常有重疊性,可以找出與之關聯性高的其他特徵,保留部分特徵並移除原先觀察之特徵。
監督式學習適用的特徵選擇
- 過濾方法 Filter Method
- 關聯分析 Correlation。
- 單變量特徵選取 Univariate feature selection
- 包裝方法 Wrapper Method
- 前向消除 Forward elimination
- 後向消除 Backward elimination
- 遞迴特徵消除 Recursive feature elimination (RFE)
- 嵌入方法 Embedded Method
- 重要特徵 Feature importance
- L1正規化 L1 regularization
特徵選擇示範,鐵達尼存活資料集為例
- 資料集為經整理過後的鐵達尼號資料集,Model主要以
sklearn.ensemble.RandomForestClassifier
進行示範,程式碼參考 Machine Learning Data Lifecycle in Production 課程,經過改並以不同資料及呈現過程,執行細節請參見 Colab 實作範例。
0. 前置處理
整理特徵 X ,部分屬於分類資料可以用 One-Hot Encoding編碼,並且處理無效欄位。
定義評估模型,固定以
RandomForestClassifier
模型進行訓練,並對照各測試資料集之績效。def use_RandomForestClassifier_evaluation_metrics_on_test_set(X,Y):
X_train, X_test, Y_train, Y_test = train_test_split(
X, Y, test_size = 0.2 ,stratify=Y, random_state = 9527)
# 標準化
scaler = StandardScaler().fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
# RandomForestClassifier訓練模型
model = RandomForestClassifier(criterion='entropy', random_state=9527)
model.fit(X_train_scaled, Y_train)
# 預測
y_predict_result = model.predict(X_test_scaled)
# 回傳evaluation_metrics_on_test_set
return {
'accuracy' : accuracy_score(Y_test, y_predict_result),
'roc' : roc_auc_score(Y_test, y_predict_result),
'precision' : precision_score(Y_test, y_predict_result),
'recall' : recall_score(Y_test, y_predict_result),
'f1' : f1_score(Y_test, y_predict_result),
'Feature Count' : len(X.columns)
}查看關聯性,越淺代表高度正相關,越深代表高度負相關,關聯性介於 [1,-1] 之間。
1. 特徵選擇 - 過濾方法 Filter Method
1.1 依關聯性移除特徵
選擇具有與其他特徵高度相關的某特徵 ,設定閾值選取符合特徵,並移除該特徵。本次實作挑選的是
FamilySize
,選擇超過門檻值的有代表性的特徵(無論正負相關 >0.2 ),並移除FamilySize
本身。# 取得具有與其他部分特徵高度相關的某特徵絕對值
cor_target = abs(cor["FamilySize"])
# 選擇高度相關的特徵(閾值 = 0.2)
relevant_features = cor_target[cor_target>0.2]
# 選擇特徵名稱
names = [index for index, value in relevant_features.iteritems()]
# 刪除目標特徵
names.remove('FamilySize')
print(names)
- 對比未篩選的成績,特徵減少至9個,多數指標分數下降,recall維持不變。
1.2 單變量特徵選取 Univariate Selection
- 以
sklearn.feature_selection.SelectKBest
選擇最具影響力的特徵,這邊示範 選取10
個特徵。
- 以
2. 特徵選擇 - 包裝方法 Wrapper Method
- 2.1 遞迴特徵消除 Recursive feature elimination (RFE)
以
sklearn.feature_selection.RFE
篩選,設定篩選出k=10
個重要特徵,該設定也是超參數,您可以自行設定。# Recursive Feature Elimination
def rfe_selection( X , Y, k=10):
# Split train and test sets
X_train, X_test, Y_train, Y_test = train_test_split(
X,
Y,
test_size = 0.2,
stratify=Y,
random_state = 9527)
scaler = StandardScaler().fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
model = RandomForestClassifier(
criterion='entropy',
random_state=9527
)
rfe = RFE(model, k)
rfe = rfe.fit(X_train_scaled, Y_train)
feature_names = X.columns[rfe.get_support()]
return feature_names
3. 特徵選擇 - 重要特徵 Feature importance
- 依重要性門檻值篩選特徵
- 示範以
sklearn.feature_selection.SelectFromModel
選擇,以threshold=0.013
作為篩選。
- 示範以
最終特徵選擇比較
- 經過一系列的特徵選擇,您可以視需求選擇所要採取的特徵,您追求準確率的話「遞迴特徵消除 Recursive feature elimination (RFE) 」分數最高,原本特徵從16個減少為10個,成功減少 37.5% ,運算資源可以大幅減少,而且各項指標成績都優於全數選取的結果。
- 您會發現過程中有許多超參數是可以自行調整的,在您的手上或許仍有優化空間,譬如將RFE的特徵改 k=9 試試看,性能與成績還可以再提升。
小結
- 特徵選擇相當有用,當在持續需要學習的情境,微小的節省資源手段都能帶來龐大的成本效益,您已經學會如何幫老闆、幫您自己省時、省錢了!
- 收藏起來以後用自己的資料集試試吧,希望能幫助到您。